//唐崇展
#include "Scheduler.h"
#include "Code/Simulator.h"
#include <QDebug>
#include <algorithm>

Scheduler::Scheduler(QObject* parent, std::string algoType, Simulator* simulator) :
    QObject(parent),
    sim(simulator),
    algorithmType(algoType)
{
    if (!sim) {
        qWarning() << "调度器初始化警告：未关联Simulator实例";
    }
}
void Scheduler::setAlgorithmType(const std::string& type)
{
    algorithmType = type;
    qDebug() << "调度算法已切换为：" << QString::fromStdString(type);
}

// SOC初始值为0，时间步长为1小时
float Scheduler::calculateEssSoc(int currentTime) {
    if (!sim || currentTime < MIN_TIME_STEP || currentTime > MAX_TIME_STEP) {
        return 0.0f;  // 初始SOC为0
    }

    // SOC初始值=0（总能量=0）
    float totalEnergy = 0.0f;

    // 时间步长为1小时
    const float timeStepHour = 1.0f;

    // 累加历史充放电能量（功率×1小时=能量kWh）
    for (int t = MIN_TIME_STEP; t < currentTime; t++) {
        float essPower = sim->energyStorageTimePowerMap.value(t, 0.0f);
        totalEnergy += essPower * timeStepHour;
    }

    // SOC=总能量/储能容量（限制在0~1）
    float soc = totalEnergy / sim->energyStorageCapacity;
    return std::clamp(soc, 0.0f, 1.0f);
}

void Scheduler::onSimulationTime(int currentTime) {
    if (currentTime < MIN_TIME_STEP || currentTime > MAX_TIME_STEP) {
        qWarning() << "时间步超出范围(0-23)：" << currentTime;
        return;
    }

    if (!sim) {
        qWarning() << "未关联Simulator，无法调度";
        return;
    }

    qDebug() << "调度时间步（小时）：" << currentTime;

    // 执行调度，直接修改映射表
    executeScheduling(currentTime);

    // 从映射表获取最新功率数据（按光伏、储能、柴油、电网顺序）
    QList<double> powerData;
    powerData.append(sim->pvTimePowerMap.value(currentTime, 0.0f));        // 光伏功率
    powerData.append(sim->energyStorageTimePowerMap.value(currentTime, 0.0f));  // 储能功率
    powerData.append(sim->dieselGenTimePowerMap.value(currentTime, 0.0f));   // 柴油发电机功率
    powerData.append(sim->gridTimePowerMap.value(currentTime, 0.0f));       // 电网功率

    // 发射调度完成信号
    emit scheduleCompleted(powerData);
}

void Scheduler::executeScheduling(int currentTime) {
    if (algorithmType == "经济调度") {
        economicDispatch(currentTime);
    } else {
        ruleBasedDispatch(currentTime);
    }
}

// 经济调度（适配1小时步长，直接修改映射表）
void Scheduler::economicDispatch(int currentTime) {
    if (!sim) return;

    // 从映射表获取当前小时的实时数据
    float pvOutput = sim->pvTimePowerMap.value(currentTime, 0.0f);         // 光伏出力（kW）
    float totalLoad = sim->loadTimePowerMap.value(currentTime, 0.0f);       // 负载需求（kW）
    float gridPrice = sim->gPriceTimePriceMap.value(currentTime, 0.0f);     // 电价（元/kWh）
    float essSoc = calculateEssSoc(currentTime);                            // 储能SOC

    // 从Simulator获取硬编码参数
    float dieselMax = sim->dieselGenMaxPower;
    float dieselMin = sim->dieselGenMinPower;
    float dieselCost = sim->getDieselCostPerKwh();
    float essCapacity = sim->energyStorageCapacity;  // 储能容量（kWh）

    float remainingLoad = totalLoad;
    float pvPower = 0.0f, essPower = 0.0f, dieselPower = 0.0f, gridPower = 0.0f;

    // 1. 光伏优先消纳
    pvPower = std::min(pvOutput, remainingLoad);
    remainingLoad -= pvPower;

    // 2. 储能放电（SOC>0.2，1小时内最大放电量=容量×20%）
    if (essSoc > 0.2f && remainingLoad > 0) {
        float maxDischarge = essCapacity * 0.2f;
        essPower = -std::min(remainingLoad, maxDischarge);  // 负号表示放电
        remainingLoad -= std::abs(essPower);
    }

    // 3. 柴油发电机（成本低于电网时）
    if (remainingLoad > 0 && dieselCost < gridPrice) {
        dieselPower = std::clamp(remainingLoad, dieselMin, dieselMax);
        remainingLoad -= dieselPower;
    }

    // 4. 电网购电
    if (remainingLoad > 0) {
        gridPower = remainingLoad;
        remainingLoad = 0;
    }

    // 5. 光伏过剩充电（SOC<0.9，1小时内最大充电量=容量×15%）
    float excessPv = pvOutput - pvPower;
    if (excessPv > 0 && essSoc < 0.9f) {
        float maxCharge = essCapacity * 0.15f;
        essPower = std::min(excessPv, maxCharge);  // 正号表示充电
    }

    // 直接更新映射表（当前小时的功率）
    sim->dieselGenTimePowerMap[currentTime] = dieselPower;
    sim->energyStorageTimePowerMap[currentTime] = essPower;
    sim->gridTimePowerMap[currentTime] = gridPower;
    qDebug()<<"diaodu__wancheng";
}

// 规则调度（适配1小时步长，直接修改映射表）
void Scheduler::ruleBasedDispatch(int currentTime) {
    if (!sim) return;

    float pvOutput = sim->pvTimePowerMap.value(currentTime, 0.0f);
    float totalLoad = sim->loadTimePowerMap.value(currentTime, 0.0f);
    float essSoc = calculateEssSoc(currentTime);
    float dieselMax = sim->dieselGenMaxPower;
    float dieselMin = sim->dieselGenMinPower;
    float essCapacity = sim->energyStorageCapacity;

    float remainingLoad = totalLoad;
    float essPower = 0.0f, dieselPower = 0.0f, gridPower = 0.0f;

    // 1. 光伏优先
    remainingLoad -= pvOutput;
    if (remainingLoad < 0) remainingLoad = 0;

    // 2. 储能放电（SOC>0.3）
    if (essSoc > 0.3f && remainingLoad > 0) {
        float maxDischarge = essCapacity * 0.2f;
        essPower = -std::min(remainingLoad, maxDischarge);  // 负号表示放电
        remainingLoad -= std::abs(essPower);
    }

    // 3. 柴油发电机
    if (remainingLoad > 0) {
        dieselPower = std::clamp(remainingLoad, dieselMin, dieselMax);
        remainingLoad -= dieselPower;
    }

    // 4. 电网购电
    if (remainingLoad > 0) {
        gridPower = remainingLoad;
    }

    // 更新映射表
    sim->dieselGenTimePowerMap[currentTime] = dieselPower;
    sim->energyStorageTimePowerMap[currentTime] = essPower;
    sim->gridTimePowerMap[currentTime] = gridPower;
    qDebug()<<"diaodu__wancheng";
}
